﻿/******************************************************************
 *Company: http://www.xiaomutech.com/
 *fileName : qabstractlistwidget.cpp --- QAbstractListWidget
 *Auth       : yhni (QQ:393320854)
 *Create    : 2022/9/15
 *Description   :
 *Histroy:
 *<Auth>    <Date>        <Ver>        <Content>
 *         2022/9/15
 *******************************************************************/
#include "qabstractlistwidget.h"

#include <QMouseEvent>
#include <QPainter>
#include <QScrollBar>
#include <QDebug>

QAbstractListWidget::QAbstractListWidget(QWidget *parent) : QAbstractScrollArea(parent)
{
    this->setMouseTracking(true);
    this->setFrameShape(QFrame::NoFrame);
    this->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjustSize()));

    m_backgroundColor = "#f1f2f3";
    m_textColor       = "#9acd32";

    m_itemSize = 60;
    m_itemSpace = 1;
    m_currentIndex = -1;
    m_hoverIndex  = -1;
    m_strEmptyHint = QStringLiteral("正在加载，请稍后...");
}

QAbstractListWidget::~QAbstractListWidget()
{
    clear();
}

void QAbstractListWidget::clear()
{
    foreach(QAbstractListItem *_item, m_items) {
        m_items.remove(_item->id());
        delete _item;
        _item = NULL;
    }

    adjustSize();
}

void QAbstractListWidget::addItem(QAbstractListItem *_item)
{
    if (!m_items.contains(_item->id()))
    {
        m_items.insert(_item->id(), _item);
        if (-1 == m_currentIndex)
        {
            m_currentIndex = _item->id();
            _item->setChecked(true);
            emit itemClicked(_item);
        }
        adjustSize();
    }
}

void QAbstractListWidget::deleteItem(QAbstractListItem *_item)
{
    if (m_items.contains(_item->id()))
    {
        m_items.remove(_item->id());
        delete _item;
        _item = NULL;
    }
}

void QAbstractListWidget::setPrevIndex()
{
    if (m_currentIndex > 1)
    {
        setCurrentIndex(m_currentIndex - 1);
    }
}

void QAbstractListWidget::setNextIndex()
{
    if ((m_currentIndex + 2) < m_items.size())
    {
        setCurrentIndex(m_currentIndex + 1);
    }
}

void QAbstractListWidget::setCurrentIndex(int index)
{
    if (m_currentIndex != index && m_items.contains(index))
    {
        if (-1 != m_currentIndex)
        {
            m_items.value(m_currentIndex)->setChecked(false);
        }
        m_items.value(index)->setChecked(true);
        m_currentIndex = index;
        emit itemClicked(m_items.value(index));
        adjustSize();
    }
}

QColor QAbstractListWidget::getBackgroundColor() const
{
    return m_backgroundColor;
}

void QAbstractListWidget::setBackgroundColor(const QColor &color)
{
    m_backgroundColor = color;
    viewport()->update();
}

QColor QAbstractListWidget::getTextColor() const
{
    return m_textColor;
}

void QAbstractListWidget::setTextColor(const QColor &color)
{
    m_textColor = color;
    viewport()->update();
}

void QAbstractListWidget::resizeEvent(QResizeEvent *e)
{
    adjustSize();
    QAbstractScrollArea::resizeEvent(e);
}

void QAbstractListWidget::mouseMoveEvent(QMouseEvent *e)
{
    foreach(QAbstractListItem *_item, m_items) {
        _item->setHover(_item->rect().contains(e->pos()));
        if (_item->isHover())
        {
            m_hoverIndex = _item->id();
        }
    }

    viewport()->update();
}

void QAbstractListWidget::mousePressEvent(QMouseEvent *e)
{
    foreach(QAbstractListItem *_item, m_items) {
        if (_item->rect().contains(e->pos()))
        {
            if (m_currentIndex != _item->id())
            {
                _item->setChecked(true);
                emit itemClicked(_item);
                m_currentIndex = _item->id();
            }
        }
        else {
            _item->setChecked(false);
        }
    }

    viewport()->update();
}

void QAbstractListWidget::leaveEvent(QEvent *e)
{
    foreach(QAbstractListItem *_item, m_items) {
        _item->setHover(false);
    }

    m_hoverIndex = -1;
    clearRects();
    viewport()->update();
    QAbstractScrollArea::leaveEvent(e);
}

void QAbstractListWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(viewport());
    painter.setRenderHints(QPainter::Antialiasing);
    painter.fillRect(viewport()->rect(), m_backgroundColor);
    painter.setPen(m_textColor);

    if (m_items.isEmpty())
    {
        painter.drawText(viewport()->rect(), Qt::AlignCenter, m_strEmptyHint);
    }

    foreach(QAbstractListItem *_item, m_items) {
        if (_item->rect().width() > 0 && _item->rect().bottom() > 0) {
            drawItemInfo(&painter, _item);
        }
    }
}

void QAbstractListWidget::drawIconfont(QPainter *painter, const QRect &_rect, QChar _ico, QColor _color, int _size)
{
    painter->save();
    QFont font("iconfont");
    font.setPixelSize(_size);
    painter->setFont(font);
    painter->setPen(_color);
    painter->drawText(_rect, Qt::AlignCenter, _ico);
    painter->restore();
}

void QAbstractListWidget::drawItemInfo(QPainter *painter, QAbstractListItem *_item)
{
    painter->save();
    painter->drawRect(_item->rect());
    painter->restore();
}

void QAbstractListWidget::adjustSize()
{
    int barValue = verticalScrollBar()->value();
    int nYoffset = 2;
    int nXoffset = 2;
    foreach(QAbstractListItem *_item, m_items) {
        if (nYoffset - barValue < viewport()->height()) {
            _item->setRect(QRect(nXoffset, nYoffset - barValue, viewport()->width() - nXoffset * 2, m_itemSize));
        } else {
            _item->setRect(QRect(0, 0, -1, -1));
        }

        nYoffset += m_itemSize;
        nYoffset += m_itemSpace;
    }

    nYoffset = nYoffset > viewport()->height() ? (nYoffset - viewport()->height()) : 0;
    verticalScrollBar()->setRange(0, nYoffset);
    verticalScrollBar()->setPageStep(viewport()->height());
    verticalScrollBar()->setSingleStep(10);
    viewport()->update();
}

void QAbstractListWidget::clearRects()
{

}

////////////////////////////////////////////////////////////////////////
QAbstractListItem::QAbstractListItem() : QObject(NULL),
    m_id(0), m_rect(0, 0, 0, 0)
{
    m_hover = false;
    m_checked = false;
}

QAbstractListItem::QAbstractListItem(int _id) : QObject(NULL),
    m_id(_id), m_rect(0, 0, 0, 0)
{
    m_hover = false;
    m_checked = false;
}

int QAbstractListItem::id() const
{
    return m_id;
}

void QAbstractListItem::setRect(const QRect &_rect)
{
    m_rect = _rect;
}

QRect QAbstractListItem::rect()
{
    return m_rect;
}


bool QAbstractListItem::isHover() const
{
    return m_hover;
}

void QAbstractListItem::setHover(bool bOk)
{
    m_hover = bOk;
}

bool QAbstractListItem::isChecked()
{
    return m_checked;
}

void QAbstractListItem::setChecked(bool bOk)
{
    m_checked = bOk;
}
